package com.photoeditor.demo.util;

import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.TextUtils;

import com.common.base.ComponentContext;
import com.photoeditor.demo.model.image.util.ImageHelper;
import com.photoeditor.demo.model.bean.BitmapBean;

import java.io.InputStream;

public class BitmapDecoder {

    /**
     * 获取指定大小的缩略图
     * @param path
     * @param imageWidth
     * @param degree
     * @return
     *
     * imageWidth的大小的计算方法如下
     *  int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int max = Math.max(width, height);
        if (max > boundSize) {
        float scale = boundSize * 1.0f / max;
        int w = Math.round(scale * width);
        int h = Math.round(scale * height);
        bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
        }
     */
    public static Bitmap getThumb(String path, int degree, int imageWidth) {
        Bitmap bitmap = null;
        MediaFile.MediaFileType fileType = MediaFile.getFileType(path);
        if ( fileType == null ) {
            return null;
        }
        if ( MediaFile.isVideoFileType(fileType.fileType) ) {
            bitmap = MediaThumbnailUtil.getInstance().getVideoThumbnail(path, imageWidth <= ImageManageUtil.SMALL_IMAGE_WIDTH ? ImageManageUtil.MIDDLE_IMAGE_WIDTH : imageWidth);
        } else if (MediaFile.isImageFileType(fileType.fileType)) {
            bitmap = MediaThumbnailUtil.getInstance().getImage(path, imageWidth, degree);
        } else if(MediaFile.isEncryptImageType(fileType.fileType)){
            bitmap = MediaThumbnailUtil.getInstance().getEncryptImage(path, imageWidth, degree);
        } else if(MediaFile.isEncryptVideoType(fileType.fileType)){
            bitmap = MediaThumbnailUtil.getInstance().getVideoThumbnail(path, imageWidth <= ImageManageUtil.SMALL_IMAGE_WIDTH ? ImageManageUtil.MIDDLE_IMAGE_WIDTH : imageWidth);
        }
        return bitmap;
    }

    /**
     * 异步获取图片
     * @param path
     * @param degree
     * @param imageWidth
     * @param listener
     */
    public static void getBitmap(final String path, final int degree, final int imageWidth, final com.photoeditor.demo.model.share.ILoadBitmap listener){
        new AsyncTask<Void, Void, Bitmap>() {

            @Override
            protected Bitmap doInBackground(Void... params) {
                return BitmapDecoder.getThumb(path, degree, imageWidth);
            }

            protected void onPostExecute(Bitmap result) {
                super.onPostExecute(result);
                if(listener != null){
                    listener.onLoadOver(result);
                }
            }
        }.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR);
    }

    /**
     * 根据Uri异步获取图片
     * @param u
     * @param imageWidth
     * @param listener
     */
    public static void asycGetBitmap(Uri u, int imageWidth, com.photoeditor.demo.model.share.ILoadBitmap listener){
        BitmapBean bean = ImageHelper.getInterBitmapBeanFormUri(ComponentContext.getContext(), u);
        getBitmap(bean.mPath, bean.mDegree, imageWidth, listener);
    }

    /**
     * 解析到可以预览的大小
     * 里面没有异步处理注意自己异步
     * @param u
     * @return
     */
    public static Bitmap UriDecodeToPreviewBitmap(final Uri u){
        BitmapBean bean = ImageHelper.getInterBitmapBeanFormUri(ComponentContext.getContext(), u);
        if(MediaTypeUtil.isVideo(bean.mType)){
            return ImageHelper.videoToBitmap(bean);
        } else{
            return decodeImage2BitmapPreview(bean.mUri, bean.mDegree);
        }
    }

    /**
     * 将图片Uri转成预览图
     * @param u
     * @param degree
     * @return
     */
    public static Bitmap decodeImage2BitmapPreview(Uri u, int degree){
        Context context = ComponentContext.getContext();
        int insamplesize = 1;
        Bitmap bitmap = null;
        ContentResolver mCr = context.getContentResolver();
        Resources res = context.getResources();
        BitmapFactory.Options option=new BitmapFactory.Options();
        InputStream in1 = null;
        InputStream in2 = null;
        InputStream in3 = null;
        try {
            option.inJustDecodeBounds=true;
            in1 = mCr.openInputStream(u);
            bitmap = BitmapFactory.decodeStream(in1, null, option);
			/*
			 * 原来的长宽
			 */
            int width;
            int height;

            if(degree == 90 || degree == 270){
                width = option.outHeight;
                height = option.outWidth;
            }else{
                width = option.outWidth;
                height = option.outHeight;
            }
            option.inJustDecodeBounds =false;
            option.inPreferredConfig = Bitmap.Config.ARGB_8888;
            option.inPurgeable = true;
            option.inInputShareable = true;
            option.inDither = false;

            float scale = ImageHelper.getFitSampleSize(width, height);
            scale = ImageHelper.checkCanvasAndTextureSize(width, height, scale);

            int i = 1;
            while(scale / Math.pow(i, 2) > 1.0f){
                i *= 2;
            }
            if(i != 1) {
                i = i / 2;
            }
            insamplesize = i;

            int targetDensity = res.getDisplayMetrics().densityDpi;
            option.inScaled = true;
            option.inDensity = (int)(targetDensity * Math.sqrt(scale / Math.pow(i, 2)) + 1);
            option.inTargetDensity = targetDensity;

            option.inSampleSize = insamplesize;

            in2 = mCr.openInputStream(u);
            bitmap = BitmapFactory.decodeStream(in2, null, option);
            bitmap = ImageHelper.rotatingAndScale(bitmap, degree);
        } catch (Throwable e) {
            System.gc();
            e.printStackTrace();
            //如果内存溢出 缩小1/4再解析
            option.inSampleSize = insamplesize * 2;
            try {
                in3 = mCr.openInputStream(u);
                bitmap = BitmapFactory.decodeStream(in3, null, option);
                bitmap = ImageHelper.rotatingAndScale(bitmap, degree);
            } catch (Throwable e1) {
                System.gc();
                e1.printStackTrace();
            }
            return bitmap;
        } finally{
            try {
                if(in1 != null){
                    in1.close();
                }
                if(in2 != null){
                    in2.close();
                }
                if(in3 != null){
                    in3.close();
                }
            } catch (Throwable e) {
            }
        }
        return bitmap;
    }

    /**
     * 社区用于压缩编辑界面产生的图片
     * @return
     */
    public static Bitmap scaleBitmapToUpload(Bitmap bitmap){
        if(bitmap == null) return null;
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        float scale = ImageHelper.getShareFitSampleSize(width, height);
        if(scale <= 1.0f){
            return bitmap;
        }
        scale = (float)Math.sqrt(scale);
        int newWidth = (int)(width / scale);
        int newHeight = (int)(height / scale);
        return scaleBitmap(bitmap, newWidth, newHeight, false);
    }

    /**
     * 放大图片 通用方法
     * @param bitmap
     * @param newWidth
     * @param newHeight
     * @return
     */
    public static Bitmap scaleBitmap(Bitmap bitmap, int newWidth, int newHeight, boolean recycle){
        try {
            Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
            if(recycle && bitmap != newBitmap){
                bitmap.recycle();
            }
            return newBitmap;
        } catch (Throwable e) {
            e.printStackTrace();
            System.gc();
        }
        return bitmap;
    }

    /**
     * 用于判断图片是否有效, 如果无效不进行处理,需要异步调用,耗时
     * @param path
     * @return
     */
    public static boolean isVaildImage(String path){
        if(TextUtils.isEmpty(path)) return false;
        try {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, options);
            if(options.outMimeType == null){
                return false;
            }
            return true;
        } catch (Throwable e){
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 用于判断图片是否有效, 如果无效不进行处理,需要异步调用,耗时
     * @param stream
     * @return
     */
    public static boolean isVaildImage(InputStream stream){
        if(stream == null) return false;
        try {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(stream, null, options);
            if (options.outMimeType == null) {
                return false;
            }
            stream.close();
            return true;
        } catch (Throwable e){
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 社区用于压缩编辑界面产生的图片
     * @return
     */
    public static Bitmap scaleBitmap4Detect(Bitmap bitmap) {
        if(bitmap == null) {
            return null;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        float scale;
        // 人脸识别的图片，宽度或高度不超过480
        int max = 480;
        if (width > height) {
            scale = (float) max / width;
        } else {
            scale = (float) max / height;
        }

        if(scale >= 1.0f) {
            return bitmap;
        }
        int newWidth = (int)(width * scale);
        int newHeight = (int)(height * scale);
        return scaleBitmap(bitmap, newWidth, newHeight, false);
    }
}
